#include <zmq/zmq.h>
#include <zsystem/core/common/assert.h>
#include <zsystem/core/common/log.h>
#include <iostream>

int main(int argc, char *argv [])
{
  int exitCode = 0;
  void* ctx = zmq_init(1);
  Z_ASSERT_ALL(ctx != NULL);
  void *socket = zmq_socket(ctx, ZMQ_REP);
  Z_ASSERT_ALL(socket != NULL);

  int rc = zmq_bind (socket, "tcp://127.0.0.1:5560");
  Z_ASSERT_ALL(rc == 0);

  std::cout<<"zmq_rep ready"<<std::endl;

  Z_I64 more;
  Z_I32 moreSize = sizeof(more);
  while(1)
  {
    zmq_msg_t msg;
    rc = zmq_msg_init (&msg);
    std::cout<<"waiting message ..."<<std::endl;

    rc = zmq_recv(socket, &msg, 0);
    if(rc != 0)
    {
      std::cout << "zmq_recv failed, return = " << rc << ", errno = " << errno << " - " << Z_STRING_ERROR(errno) << std::endl;
      exitCode = -1;
      break;
    }
    std::string str((const char *)zmq_msg_data(&msg), zmq_msg_size(&msg));
    std::cout << "received: " << str << std::endl;
    zmq_msg_t& reply = *(&msg);
    //zmq_msg_init_size (&reply, str.length());
    //memcpy(zmq_msg_data(&reply), str.c_str(), str.length());
    rc = zmq_send(socket, &reply, 0);
    if(rc != 0)
    {
      std::cout << "zmq_send failed, return = " << rc << ", errno = " << errno << " - " << Z_STRING_ERROR(errno) << std::endl;
      exitCode = -1;
      break;
    }
    if(str.compare("exit") == 0)
    {
      std::cout<<"Exit"<<std::endl;
      break;
    }
  }
  rc = zmq_close (socket);
  if(rc != 0)
  {
    std::cout << "zmq_close failed, return = " << rc << ", errno = " << errno << " - " << Z_STRING_ERROR(errno) << std::endl;
    exitCode = -1;
  }

  rc = zmq_term (ctx);
  if(rc != 0)
  {
    std::cout << "zmq_term failed, return = " << rc << ", errno = " << errno << " - " << Z_STRING_ERROR(errno) << std::endl;
    exitCode = -1;
  }

  return exitCode;
}
